package com.zzr.demo.rabbitmq.service.impl;

import com.rabbitmq.client.Channel;
import com.zzr.demo.rabbitmq.model.Dog;
import com.zzr.demo.rabbitmq.model.Person;
import com.zzr.demo.rabbitmq.service.ListenerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

import java.io.IOException;

/**
 * @author: xiaomi
 * @date: 2021/8/25
 * @description: NOTEME RabbitListener 和 RabbitHandler 组合是为了解决：queue 中存在多种对象的情况！
 * 此时 RabbitListener 无法解决转换的问题：
 * 方法依然可以接收消息，但是转换失败！所以此时有了下面的模式：
 * RabbitListener 监听一个类；
 * RabbitHandler 监听类中的某个方法，方法头注明对象类型即可，这样转换的对象就能对应到各自的方法里；
 */
@Service("combineListenerService")
@Slf4j
@RabbitListener(queues = {"sample1-java-queue"})
public class CombineListenerServiceImpl implements ListenerService {


    @RabbitHandler
    public void receiveMessageInSample1InCombineV1Person(Message message, Person person, Channel channel) {
        log.info("coming receiveMessageInSample1InCombineV1Person...");
        log.info("接收到消息，内容为：{}，类型为：{}", message, message.getClass());
        log.info("消息体：{}", person);
        log.info("信道：{};", channel);

    }

    /**
     * nack/没有执行 ack/reject 后选择入队的话，就会一直监听到内容（消息状态变为：Unacked）
     *
     * @param message
     * @param dog
     * @param channel
     */
    @RabbitHandler
    public void receiveMessageInSample1InCombineV1Dog(Message message, Dog dog, Channel channel) {
        log.info("coming receiveMessageInSample1InCombineV1Dog...");
        log.info("接收到消息，内容为：{}，类型为：{}", message, message.getClass());
        log.info("消息体：{}", dog);
        log.info("信道：{};", channel);
        try {
            //multiple 是否批量
            //requeue true:重新入队；false:丢弃

            //channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
        } catch (IOException e) {
            //网络中断
            e.printStackTrace();
        }
    }
}
